import math
import numpy
import pylab
import csv
import re

import Movie
import WetNeuron

class BrainSlice:
    '''
    represents all of the data gathered from a single slice (wet experiment).
    probably ill also be able to use this to represent the data from a single
    network (simulated experiment) but we'll see. 
    '''

    def __init__(self, firstnum, lastnum, directoryString, movieFilePreString, movieFilePostString, contourFilePreString, contourFilePostString):
	'''
	make a new one:
	the assumption is that you've got sine files in CSV format
	that have a binary record of spiking in some time-bin,
	and they're formatted something like :
	MyFavoriteSlice-Movie_number_XXX_spikerecord.csv
	so we'll be able to read them in by counting from 1 to numFiles
	and concatenating preString, count, and postString, in that order. 
	@param firstnum : we start with the nth movie , n = firstfilenum
	@param lastnum : number of the last movie (inclusive - if your last movie is #20, this number should be 20)
	@param directoryString: the directory for all the activity and contour files. needs to end in a slash so we can append other filenames to it.
	@param movieFilePreString: the first part of the file name, up to the number, for the binary activity movie - matrix
	@param movieFilePostString: the rest of the file name, after the number
	@param contourFilePreString: first part of filename, up to the number, for the individual neuron's contours
	@param contourFilePostString: rest of filename.
	'''

	#we can pre-allocate for number of movies, because they had to tell us that :
	self.movies = [None]*((lastnum+1) - firstnum) #creates a list of appropriate length. 
	self.directory = directoryString
	#we want the ID to be the topmost directory.
	#first: figure out which slash is the directory delimiter in this OS
	delimit = '/'
	if(directoryString.find(delimit) < 0): #find returns -1 if the char isn't in the string
	    delimit = '\\'   #this is really just one slash - it's the escape character
	dirTree = directoryString.split(delimit)
	self.ID = dirTree[(len(dirTree) - 2)] #this should be the topmost directory

	for i in xrange(firstnum, (lastnum+1)):
	    filename = ''.join([directoryString, movieFilePreString,`i`, movieFilePostString])
	    #print(filename)
	    datafile = csv.reader(open(filename, 'rb'))
	    #now we have an object where we can call 'next' for each neuron
	    #if this is the first time, we're just going to have to count?

	    movienrns = []
	    #one row is one neuron
	    for row in datafile:
		movienrns.append(map(int, row)) #the row gets read in as chars, so we map the int constructor down the array to get an array of ints . then we append that to our array of arrays. !

	    #use a regular expression to strip the moviename out of the filename:
	    regTemp = re.search('slice[0-9]*-20x[0-9]*', filename)
	    self.movies[i-firstnum] = Movie.Movie(movienrns, self, regTemp.group(), str(i))

	numNrns = self.movies[0].numNeurons
	self.neurons = [None]*(numNrns)
	for i in xrange(numNrns):
	    self.neurons[i] = WetNeuron.WetNeuron(i, self, directoryString, contourFilePreString, contourFilePostString)




#----------------------------------------------------------------------------printself
    def printself(self):
	print ('SliceID: '+self.ID)
	print (str(len(self.neurons))+' neurons')
	print ('in '+str(len(self.movies))+' movies')


#------------------------------------------------------------------------------saveAllMovieStrips	
    def saveAllMovieStrips(self, movieList = None):
	'''
	saves the framestrips for each movie, or only the movies specified in movielist.
	@param movieList : should be a list of indices (not movie pointers)
	'''

	if(movieList == None):
	    movieList = range(len(self.movies))

	for index in movieList:
	    self.movies[index].saveFrameStrip()


#----------------------------------------------------------------------------------saveCoreCells
    def saveCoreCells(self, movieList = None):
        '''
        attempts to identy core cells just by doing a timeless AND
        across all movies specified. You specify movies by passing
        in a list or array of movie indices (as opposed to movie string IDs).
        If no movieList is specified, then all movies are used.
        '''
        if (movieList == None):
            movieList = range(len(self.movies))

        if(len(movieList) < 2):
            if(len(movieList)==0):
                raise('tried to find core cells across zero movies!')
            else:
                print('why are you looking for core cells across %d movies?' %
                          len(movieList))

        
        #start with the last movie in the list, removing it from the list so we don't AND against it later.
        m = self.movies[movieList.pop()]
	firstname = m.shortID
        
        for index in movieList:
            m = m.timelessAnd(self.movies[index])

        movienames = ''.join([ ''.join(', ',self.movies[index].shortID) for index in movieList])
	m.ID = 'putative core cells in movies '+movienames+'and '+firstname
	m.shortID = 'core: '+movienames+firstname
	return m


    def plotSlice(self, axes = None):
	'''
	plots just an outline of each neuron in the slice.
	either creates a new figure and passes you back a reference to the figure,
	OR if you pass in axes it just uses those,  and it returns None
	'''
	if(axes == None):
	    fig = pylab.figure()
	    fig.hold(True)
	    axes = fig.gca()
	else:
	    fig = None

	for neuron in self.neurons:
	    neuron.plot(axes)

	#fig.show()
	return fig



def slice2_20081015():
    dir = '/Users/joekimmel/Desktop/SLICEDATA/20081015-slice2/'
    moviePre = 'binaryActivity - slice2-20x'
    moviePost = '.tif.txt'

    contoursPre = ''
    contoursPost = 'contour.csv'
    s = BrainSlice(4, 11, dir, moviePre, moviePost, contoursPre, contoursPost)
    return s

def slice1_20081211():
    dir = '/Users/joekimmel/Desktop/SLICEDATA/20081211/'
    moviePre = 'binaryActivity - slice1-20x'
    moviePost = '.tif.txt'

    contoursPre = ''
    contoursPost = 'contour.csv'
    s = BrainSlice(2, 12, dir, moviePre, moviePost, contoursPre, contoursPost)

    s.movies[0].protocol='VB'
    s.movies[1].protocol='L6'
    s.movies[2].protocol='VB'
    s.movies[3].protocol='L6'
    s.movies[4].protocol='phase-lag'
    s.movies[5].protocol='priming'
    s.movies[6].protocol='phase-lag'
    s.movies[7].protocol='VB'
    s.movies[8].protocol='L6'
    s.movies[9].protocol='phase-lag'
    s.movies[10].protocol='phase-lead'

    return s


def slice1_20081013():
    dir = '/Users/joekimmel/Desktop/SLICEDATA/20081013-slice1/'
    moviePre = 'binaryActivity - slice1-20x'
    moviePost = '.tif.txt'

    contoursPre = ''
    contoursPost = 'contour.csv'
    s = BrainSlice(1, 16, dir, moviePre, moviePost, contoursPre, contoursPost)
    return s


def slice2_20081014():
    dir = '/Users/joekimmel/Desktop/SLICEDATA/20081014-slice2/'
    moviePre = 'binaryActivity - slice2-20x'
    moviePost = '.tif.txt'

    contoursPre = ''
    contoursPost = 'contour.csv'
    s = BrainSlice(1, 14, dir, moviePre, moviePost, contoursPre, contoursPost)
    return s


def slice1_20081014():
    dir = 'C:\\Documents and Settings\\Joe\\Desktop\\imagingFall08\\20081014\\slice1-secondpass\\'
    moviePre = 'binaryActivity - slice1-20x'
    moviePost = '.tif.txt'
    contoursPre = ''
    contoursPost = 'contour.csv'
    return BrainSlice(2,21, dir, moviePre, moviePost, contoursPre, contoursPost)


def slice2_m812_20081004():
    dir = 'C:\\Documents and Settings\\Joe\\Desktop\\imagingFall08\\20081004\\slice2-movies8-12\\'
    moviePre = 'binaryActivity - slice2-20x'
    moviePost = '.tif.txt'
    contoursPre = ''
    contoursPost = 'contour.csv'
    return BrainSlice(8,12, dir, moviePre, moviePost, contoursPre, contoursPost)



def defaultSlice():


#    dir = '/home/lab/Desktop/SLICEDATA/20081014-slice1/'
#    dir = '/Users/joekimmel/Desktop/SLICEDATA/20081001-slice2/'
#    moviePre = 'binaryActivity - slice2-20x'
#    moviePost = '.tif.txt'

    # dir = '/Users/joekimmel/Desktop/SLICEDATA/20081001-slice2/'
    #moviePre = 'binaryActivity - slice2-20x'
    
    
    #s = BrainSlice(2, 8, dir, moviePre, moviePost, contoursPre, contoursPost)


    s = slice1_20081014()

    s.printself()
    
    phaselag = Movie.ComboMovie(s.movies, [1,4])
    #phaselag.saveFrameStrip()
    
    #VB:
    VB = Movie.ComboMovie(s.movies, [6,3])
    #VB.saveFrameStrip()

    
    #bestaligned single stims:
    bestVB = s.movies[6].bestAlignedAnd(s.movies[3])
    bestL6 = s.movies[5].bestAlignedAnd(s.movies[8])

    bestVB.plotTimeless(save=True)
    purePL = (phaselag - bestVB) 
    purePL.saveFrameStrip()

    #purePhaselag = (phaselag - s.movies[0].timelessAnd(s.movies[7])) - s.movies[6].timelessAnd(s.movies[9])
    #purePhaselag.saveFrameStrip()

    #ur = Movie.ComboMovie(s.movies, [7,1,2,5])
    #ur.saveFrameStrip()
    #ur.coreOnly().saveFrameStrip()

    #(((s.movies[7].bestAlignedAnd(s.movies[1])).bestAlignedAnd(s.movies[2])).bestAlignedAnd(s.movies[5])).saveFrameStrip()

    #individual movies:
    #s.saveAllMovieStrips()



    return s



if __name__ == "__main__":
   

    defaultSlice()
    

